/**
 * 
 */
package com.xbang.core.dao.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xbang.core.dao.support.GenericDaoSupport;


/**
 * @author dev.zhang
 */
public abstract class DynamicDaoFactory {
    
	private static final Log logger = LogFactory.getLog(DynamicDaoFactory.class);
	
	// Dao implementation class cache
	private static Map<Class<?>, Object> DAO_CACHE = new HashMap<Class<?>, Object>();
	
    /**
     * Create DynamicDao implementation using Dynamic Proxy.  May have a cache here to avoid repeatly creating the same implementation 
     * class for the same Dao interface.
     * 
     * @param clazz
     * @param genericDaoSupport
     * @return
     */
    public static Object create(Class<?> clazz, GenericDaoSupport genericDaoSupport) {
    	
    	// check the cache first, avoid creating the same implementation class repeatly
    	if(DAO_CACHE.containsKey(clazz)) {
    		
    		if(logger.isDebugEnabled()) {
    			logger.debug("Using DynamicDao implemention class " + clazz + " in Cache");
    		}
    		
    		return DAO_CACHE.get(clazz);
    	}
    	
    	// Create invocationHandler and its proxy instance
    	InvocationHandler handler = new DynamicDaoInvocationHandler(genericDaoSupport);
        Object dynamicDaoClass = Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, handler);
    		
        // put the instance into Cache
        DAO_CACHE.put(clazz, dynamicDaoClass);
            
        return dynamicDaoClass;
   }

}
